﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MFramework
{
    internal class DataLoader
    {
        private const string CONFIG_TABLE_DIR = "Assets/GameRes/Designs/";

        public static DataTable LoadConfigTable(string name)
        {
            string path = CONFIG_TABLE_DIR + name + ".json";

            using StreamReader reader = new StreamReader(path);

            DataTable dataTable = new DataTable();

            string line = null;

            if (!string.IsNullOrEmpty(reader.ReadLine()))
            {
                while (!string.IsNullOrEmpty(line = reader.ReadLine()))
                {
                    if (line.Length <= 2) continue;

                    DataTableRow rowObj = new DataTableRow();
                    int rowID = 0;

                    List<string> keyValuePairStrings = SplitKeyValePair(line);

                    for(int i = 0; i < keyValuePairStrings.Count; ++i)
                    {
                        string[] keyValueStr = SplitKeyAndValue(keyValuePairStrings[i]);
                        string keyStr = keyValueStr[0];
                        string valueStr = keyValueStr[1];

                        AddKeyValuePairToRow(keyStr, valueStr, rowObj);

                        if (i == 0)
                        {
                            rowID = int.Parse(valueStr);
                        }
                    }

                    if (rowObj.Count > 0)
                    {
                        dataTable.AddRow(rowID, rowObj);
                    }
                }
            }
            return dataTable;
        }

        private static void AddKeyValuePairToRow(string keyStr, string valueStr, DataTableRow rowObj)
        {
            string key = keyStr.Substring(1, keyStr.Length - 2);
            string value = valueStr;

            DataValueType valueType = DataValueType.Int;
            if (valueStr.StartsWith('"'))
            {
                value = valueStr.Substring(1, valueStr.Length - 2);
                valueType = DataValueType.String;
            }
            else if (valueStr.Contains("."))
            {
                valueType = DataValueType.Float;
            }

            switch (valueType)
            {
                case DataValueType.Int:
                    rowObj.SetInt(key, int.Parse(value));
                    break;
                case DataValueType.Float:
                    rowObj.SetFloat(key, float.Parse(value));
                    break;
                case DataValueType.String:
                    rowObj.SetString(key, value);
                    break;
            }
        }

        private static List<string> SplitKeyValePair(string line)
        {
            string str = null; 
            if (line.EndsWith("},"))
            {
                str = line.Substring(1, line.Length - 3);
            }
            else
            {
                str = line.Substring(1, line.Length - 2);
            }


            bool isInString = false;
            int startInd = 0;

            List<string> resultList = new List<string>();

            for(int i = 0; i < str.Length; ++i)
            {
                if(str[i] == '"' && (i == 0 || str[i - 1] != '\\'))
                {
                    isInString = !isInString;
                }
                if(str[i] == ',' && !isInString)
                {
                    resultList.Add(str.Substring(startInd, i - startInd));
                    startInd = i + 1;
                }
            }

            resultList.Add(str.Substring(startInd));

            return resultList;
        }

        private static string[] SplitKeyAndValue(string keyValueString)
        {
            string[] result = new string[2];

            bool isInString = false;

            for(int i = 0; i < keyValueString.Length; ++i)
            {
                if (keyValueString[i] == '"' && (i == 0 || keyValueString[i - 1] != '\\'))
                {
                    isInString = !isInString;
                }
                if (keyValueString[i] == ':' && !isInString)
                {
                    result[0] = keyValueString.Substring(0, i);
                    result[1] = keyValueString.Substring(i + 1);
                }
            }
            return result;
        }

        enum DataValueType
        {
            Int, Float, String
        }
    }
}
